/**
 *
 * @author   Zheng Kejun
 * @date      Aug 06, 2014
 * @version   1
 *
 * @license Ext.ux.plugin.MultiSorts is licensed under the terms of
 * the Open Source LGPL 3.0 license.  Commercial use is permitted to the extent
 * that the code/component(s) do NOT become part of another Open Source or Commercially
 * licensed development library or toolkit without explicit permission.
 * 
 * License details: http://www.gnu.org/licenses/lgpl.html
 */
Ext.namespace('Ext.ux.plugin');

/**
 * @class Ext.ux.plugin.MultiSorts
 * @extends Ext.Component
 * 
 * how to use
 * gridConfig.plugins=['multiSorts'];
 * gridConfig.plugins=[new Ext.ux.plugin.MultiSorts()]
 * gridConfig.plugins=[{ptype:'multiSorts'}]
 *
 * @constructor
 * @param {Object} config The config object
 */
Ext.ux.plugin.MultiSorts = Ext.extend(Ext.util.Observable, {

 /**
   * @cfg {String} sortNoneText
   * The message to display on item no sort (defaults to 'cancel sort')
   */
  sortNoneText: 'Cancel Sort',
  /**
   * @cfg {Number} maxSorts
   * The max size of sort fields, default 3
   * */
  maxSorts:3,
  
  /**
   * @cfg {Boolean} showCancelSort
   * Whether show the Cancel Sort menu item, default true
   * */
  showCancelSort:true,
	
  /*private*/
  sorts: [], 
  
  constructor: function(config){
    Ext.apply(this, config);
    Ext.ux.plugin.MultiSorts.superclass.constructor.call(this, config);
  },

  /**
   * Called by plug-in system to initialize the plugin for a specific grid panel
   */
  init: function(grid) {
	  if ((grid instanceof Ext.grid.GridPanel)&& (grid.getView() instanceof Ext.grid.GridView)){
		  this.grid=grid;
		  this.view=grid.getView();
		  this.addListeners();
	  }
  },

   addListeners: function() {
       if (!this.addedSortListeners) {
    	  this.grid.on('afterrender', function(){ this.initMenu(); }, this);
    	  //this.grid.on('columnmove',  function(){ this.updateSortsIcon(); },this);
	      this.view.on('refresh',  function(){this.updateSortsIcon(); },this);
          this.addedSortListeners = true;
       }
       return true;
   },
 
  initMenu : function () {
	   var gv =this.view;
       var hm = gv.hmenu;
       if ( hm ) {
           if( this.showCancelSort ){
        	   var noSortText = gv.sortNoneText?gv.sortNoneText:this.sortNoneText;//TODO from i18n;
               hm.insert(0,{itemId:'none', text:noSortText});
           }
    	   hm.un('itemclick',gv.handleHdMenuClick,gv);
           hm.on('itemclick',this.handleHdMenuClick,this);

           this.grid.un('headerclick', gv.onHeaderClick, gv);
           this.grid.on('headerclick',this.onHeaderClick, this);
       }
    },
   
  onHeaderClick : function(g, index) {
      var gv = this.view;//g.getView();
      if (gv.headersDisabled || !gv.cm.isSortable(index)) {
          return;
      }
      g.stopEditing(true);
      this.setSort(gv.cm.getDataIndex(index));
   },

  handleHdMenuClick : function(item) {
     var dataIndex = this.grid.getColumnModel().getDataIndex(this.view.hdCtxIndex);
     switch (item.getItemId()) {
          case 'asc':
        	  this.setSort(dataIndex,'ASC');
              break;
          case 'desc':
               this.setSort(dataIndex,'DESC');
               break;
          case 'none':
              this.setSort(dataIndex,'NONE');
                break;
          default:
        	  this.grid.view.handleHdMenuClickDefault(item);
      }
      return true;
  },
 
  /**
   * @private
   * Removes any sorting indicator classes from the column headers
   */
  clearHeaderSortState : function() {
	  this.sorts.splice(0, this.sorts.length);
	  this.updateSortsIcon();
  },
  
  reloadBySorts:function(){
	  var store = this.grid.getStore();
	  while(this.sorts.length>this.maxSorts){
			this.sorts.pop() ;
	  }
	  for(var i=0;i<this.maxSorts;i++){
		  var v = (i<this.sorts.length)?(this.sorts[i].field+" "+this.sorts[i].direction):'';
		  //alert('sorts['+i+']='+v);
		  store.setBaseParam('sorts['+i+']',v);  
	  }
	  store.reload({});
	  // alert("will to reload data")
	 
	  
	  //refresh data and drag column need set again ,no need , by view event:refresh; 
	 // this.updateSortsIcon();

  },

  updateSortsIcon : function() {
      var sortClasses = this.view.sortClasses;
      var headers = this.view.mainHd.select('td');
      	  headers.removeClass(sortClasses);
	  for(var i=0;i<this.sorts.length;i++){
		  var idx = this.view.cm.findColumnIndex(this.sorts[i].field);
		  if(idx==-1){continue;}
		  headers.item(idx).addClass(sortClasses["DESC"==this.sorts[i].direction?1:0]);
	  }  
   },
  
  setSort: function(dataIndex,direction){
	  var sort = this.getSort(dataIndex);
	  if( sort ){
		  var dir = this.findDirection(sort.direction,direction);
		  if(dir=="NONE") {
			  this.deleteSort(sort);
		  }else if(this.sorts[0].field==dataIndex){
			  if(sort.direction==dir){
				return;//no change;
			  }else{
				 sort.direction=dir;
			  }
		  }else{
			  this.sorts.splice(0,0,{field:dataIndex,direction:dir});
			  //this.sorts.unshift({field:dataIndex,direction:dir});
			  this.deleteSort(sort);
		  }
	  }else if("NONE"==direction){
		 return;//no change;
	  }	else{
		  var fld = {direction:(direction?direction:'ASC'),field:dataIndex};
		  this.sorts.splice(0,0,fld);
		  //this.sorts.unshift(fld);
		  /* judge in reloadBySorts
		  if( this.sorts.length>this.maxSorts ){
			  this.deleteSort(this.sorts[this.maxSorts]);
		  }
		  */
	  }
	  this.reloadBySorts();
  },
    
  deleteSort:function(sort){
	  for(var i=0;i<this.sorts.length;i++){
		  if(this.sorts[i]==sort){
			  //alert(this.sorts.length+":"+i);
			  this.sorts.splice(i,1);
			  break;
		  }
	  }	  
  },
    
  deleteSort1:function(sort){
	  var i=0;
	  for(;i<this.sorts.length;i++){
		  if(this.sorts[i]==sort)break;
	  }
	  if(i==this.sorts.length-1){
		  this.sorts.pop();  
	  }else if(i==0){
		  this.sorts.shift();
	  }else{
		  //changed the sorts ref;
		  this.sorts=this.sorts.slice(0,i).concat(this.sorts.slice(i+1));
	  }
  },
 
  getSort:function(dataIndex){
	  for(var i=0;i<this.sorts.length;i++){
		  if(this.sorts[i].field==dataIndex){
			  return this.sorts[i];
		  }
	  }  
  },
  
  findDirection:function(old,dir){
	  return dir?dir:("ASC"==old)?"DESC":"NONE";
  }
  
});

Ext.preg('multiSorts',Ext.ux.plugin.MultiSorts);

